package com.axter.libs.photo.choosephoto;

import android.Manifest;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.text.TextUtils;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.GridView;
import android.widget.ImageButton;
import android.widget.ListView;
import android.widget.Toast;

import com.axter.libs.base.adapter.ICheckedInterface;
import com.axter.libs.photo.ImageLoaderCache;
import com.axter.libs.photo.R;
import com.axter.libs.photo.display.IChoosePhotoCallBackInterface;
import com.axter.libs.photo.display.IPhotoDisplayInterface;
import com.axter.libs.photo.bean.MediaFolder;
import com.axter.libs.photo.bean.MediaInfo;
import com.axter.libs.photo.display.SimpleChoosePhotoCallBack;
import com.axter.libs.photo.display.SimplePhotoDisplay;
import com.axter.libs.photo.previewphoto.PreviewPhotoBaseActivity;
import com.axter.libs.photo.previewphoto.PreviewPhotoIntent;
import com.axter.libs.photo.previewphoto.PreviewPhotoPreviewActivity;
import com.axter.libs.photo.utils.ListMediaUtils;
import com.axter.libs.photo.widget.AutoBottomMenuDialog;

import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;

/**
 * @author axter
 */
public class ChoosePhotoActivity extends Activity implements View.OnClickListener {
    public static final String EXTRA_OUT_IMAGES = "choose_images";
    public static final String EXTRA_OUT_VIdEOS = "choose_videos";

    public static final String EXTRA_MAX_SIZE = "filecount";
    public static final String EXTRA_SINGLE = "single";
    public static final String EXTRA_SHOW_GIF = "showgif";
    public static final String EXTRA_SHOW_VIDEO = "showvideo";
    public static final String EXTRA_SHOW_CAMERA = "showcamera";
    public static final String EXTRA_CAMERA_DIR = "cameradir";
    public static final String EXTRA_MAX_SIZE_IMAGE = "maxsizeimage";
    public static final String EXTRA_MAX_SIZE_VIDEO = "maxsizevideo";
    public static final String EXTRA_CALLBACK_INTERFACE = "choosePhotoCallBackInterfacePath";
    public static final String EXTRA_DISPLAY_INTERFACE = "photoDisplayInterfacePath";

    private static final int REQUESTCODE_CAMERA = 1001;
    private static final int REQUESTCODE_PREVIEW = 1002;

    /** 图片网格 */
    private GridView gv_images;
    /** 底部条 用于计算高度 */
    private View footer;
    /** 分类按钮 */
    private Button category_btn;
    /** 预览按钮 */
    private Button preview;
    /** 完成按钮 */
    private Button finish;
    /** 返回按钮 */
    private ImageButton back;
    /** 目录对话框 */
    private AutoBottomMenuDialog folderDialog;
    /** 图片适配器 */
    private ChoosePhotoAdapter imageAdapter;
    /** 目录适配器 */
    private ChoosePhotoFolderAdapter folderAdapter;

    private final ChoosePhotoHandler handler = new ChoosePhotoHandler(this);

    /** 当前目录列表选择的位置 */
    private int currentFolderPosition = 0;
    /** 源数据 */
    private List<MediaFolder> folders;

    /** 总共可以选择多少资源 最少1 */
    private int maxSize = 1;
    /** 最大照片选择数 */
    private int maxImageSize = 1;
    /** 最大视频选择数 */
    private int maxVideoSize = 1;
    /** 单选模式 */
    private boolean isSingle = false;
    /** 显示gif */
    private boolean isShowGif = false;
    /** 显示视频 */
    private boolean isShowVideo = false;
    /** 显示拍照 */
    private boolean isShowCamera = false;
    /** 拍照目录 */
    private String cameraCacheDir;
    private String choosePhotoCallBackInterfacePath;
    private String photoDisplayInterfacePath;

    private Toast toast;
    private IChoosePhotoCallBackInterface choosePhotoCallBackInterface;
    private IPhotoDisplayInterface photoDisplayInterface;

    private int currentImageSize;
    private int currentVideoSize;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        handleIntent();
        setContentView(getContentView());
        bindViews();
        if (requestPermission(new String[]{
                Manifest.permission.READ_EXTERNAL_STORAGE,
                Manifest.permission.WRITE_EXTERNAL_STORAGE,
                Manifest.permission.CAMERA
        })) {
            handleData();
        }
    }

    protected int getContentView() {
        return R.layout.choosephoto;
    }

    protected void handleIntent() {
        if (getIntent() != null && getIntent().getExtras() != null) {
            maxSize = getIntent().getExtras().getInt(EXTRA_MAX_SIZE, maxSize);
            maxImageSize = getIntent().getExtras().getInt(EXTRA_MAX_SIZE_IMAGE, maxImageSize);
            maxVideoSize = getIntent().getExtras().getInt(EXTRA_MAX_SIZE_VIDEO, maxVideoSize);
            isSingle = getIntent().getExtras().getBoolean(EXTRA_SINGLE, isSingle);
            isShowGif = getIntent().getExtras().getBoolean(EXTRA_SHOW_GIF, isShowGif);
            isShowGif = getIntent().getExtras().getBoolean(EXTRA_SHOW_GIF, isShowGif);
            isShowVideo = getIntent().getExtras().getBoolean(EXTRA_SHOW_VIDEO, isShowVideo);
            isShowCamera = getIntent().getExtras().getBoolean(EXTRA_SHOW_CAMERA, isShowCamera);
            if (getIntent().getExtras().containsKey(EXTRA_CAMERA_DIR)) {
                cameraCacheDir = getIntent().getExtras().getString(EXTRA_CAMERA_DIR);
            }
            if (getIntent().getExtras().containsKey(EXTRA_CALLBACK_INTERFACE)) {
                choosePhotoCallBackInterfacePath = getIntent().getExtras().getString(EXTRA_CALLBACK_INTERFACE);
            }
            if (getIntent().getExtras().containsKey(EXTRA_DISPLAY_INTERFACE)) {
                photoDisplayInterfacePath = getIntent().getExtras().getString(EXTRA_DISPLAY_INTERFACE);
            }
        }
    }

    protected void bindViews() {
        gv_images = (GridView) findViewById(R.id.gv_images);
        footer = findViewById(R.id.footer);
        preview = (Button) findViewById(R.id.preview);
        finish = (Button) findViewById(R.id.finish);
        back = (ImageButton) findViewById(R.id.back);
        category_btn = (Button) findViewById(R.id.category_btn);

        preview.setOnClickListener(this);
        finish.setOnClickListener(this);
        back.setOnClickListener(this);
        category_btn.setOnClickListener(this);
    }

    private void setCallBackInterface() {
        try {
            if (!TextUtils.isEmpty(choosePhotoCallBackInterfacePath)) {
                Class clazz = Class.forName(choosePhotoCallBackInterfacePath);
                choosePhotoCallBackInterface = (IChoosePhotoCallBackInterface) clazz.newInstance();
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        if (choosePhotoCallBackInterface == null) {
            choosePhotoCallBackInterface = new SimpleChoosePhotoCallBack();
        }
    }

    private void setDisplayInterface() {
        try {
            if (!TextUtils.isEmpty(photoDisplayInterfacePath)) {
                if (photoDisplayInterface != null && photoDisplayInterface.getClass().getName().equals(photoDisplayInterfacePath)) {
                    return;
                }
                Class clazz = Class.forName(photoDisplayInterfacePath);
                photoDisplayInterface = (IPhotoDisplayInterface) clazz.newInstance();
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        if (photoDisplayInterface == null) {
            photoDisplayInterface = new SimplePhotoDisplay();
        }
        ImageLoaderCache.setDisplayInterface(photoDisplayInterface);
    }

    protected void handleData() {
        setCallBackInterface();
        setDisplayInterface();
        imageAdapter = new ChoosePhotoAdapter(isSingle, new ICheckedInterface() {
            @Override
            public boolean isChecked(int position, boolean isAdd) {
                // 选择的类型
                byte selectType = imageAdapter.getItem(position).getType();
                // 拍照不能点击
                if (selectType == MediaInfo.TYPE_CAMERA) {
                    return false;
                }
                // 已选择数目
                int size = imageAdapter.getChecked().size();
                // 有准备选一个
                if (isAdd) {
                    if (showMaxSelectedTip(selectType, imageAdapter.getChecked())) {
                        return false;
                    }
                }
                // 是否增加,减少
                if (isAdd) {
                    size += 1;
                } else {
                    size -= 1;
                }
                updateSelectedUI(size);
                return true;
            }
        });
        gv_images.setAdapter(imageAdapter);
        gv_images.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                MediaInfo mediaInfo = imageAdapter.getItem(position);
                if (mediaInfo.getType() == MediaInfo.TYPE_CAMERA) {
                    if (choosePhotoCallBackInterface != null) {
                        choosePhotoCallBackInterface.openCamera(ChoosePhotoActivity.this, cameraCacheDir, currentImageSize, maxImageSize);
                    }
                } else if (mediaInfo.getType() == MediaInfo.TYPE_VIDEO) {
                    if (choosePhotoCallBackInterface != null) {
                        choosePhotoCallBackInterface.openVideo(ChoosePhotoActivity.this, mediaInfo.getPath(), imageAdapter.isChecked(position));
                    }
                } else if (mediaInfo.getType() == MediaInfo.TYPE_IMAGE) {
                    if (choosePhotoCallBackInterface != null) {
                        choosePhotoCallBackInterface.openPreview(ChoosePhotoActivity.this, mediaInfo);
                    }
                }
            }
        });
        new Thread(new Runnable() {
            @Override
            public void run() {
                // FIXME 会泄漏Activity
                List<MediaFolder> folders = new ListMediaUtils(isShowGif, isShowVideo, isShowCamera, null).getData(ChoosePhotoActivity.this.getApplicationContext());
                Message message = new Message();
                message.what = 1;
                message.obj = folders;
                handler.sendMessage(message);
            }
        }).start();
    }

    /**
     * 提示最多选择N个提示信息
     *
     * @param selectType 选择的多媒体类型
     * @param list       媒体列表
     * @return 是否显示提示 显示说明不要选择了
     */
    private boolean showMaxSelectedTip(byte selectType, List<MediaInfo> list) {
        currentVideoSize = 0;
        currentImageSize = 0;
        for (MediaInfo info : list) {
            if (info.getType() == MediaInfo.TYPE_VIDEO) {
                currentVideoSize++;
            } else {
                currentImageSize++;
            }
        }
        if (toast == null) {
            toast = Toast.makeText(this, "", Toast.LENGTH_SHORT);
        }
        // 1.选择了图片   2.选择的图片数目大于预定义的
        if (selectType != MediaInfo.TYPE_VIDEO && currentImageSize == maxImageSize) {
            toast.setText(String.format(getString(R.string.photoselect_unit_max_select_images), maxImageSize));
            toast.show();
            return true;
        }
        // 1.选择了视频   2.选择的视频数目大于预定义的
        if (isShowVideo && selectType == MediaInfo.TYPE_VIDEO && currentVideoSize == maxVideoSize) {
            toast.setText(String.format(getString(R.string.photoselect_unit_max_select_videos), maxVideoSize));
            toast.show();
            return true;
        }
        int currentSize = list.size();
        if (currentSize == maxSize) {
            toast.setText(String.format(getString(R.string.photoselect_unit_max_select_res), maxSize));
            toast.show();
            return true;
        }
        return false;
    }

    /**
     * 完成按钮状态
     *
     * @param size
     */
    private void updateSelectedUI(int size) {
        if (size == 0) {
            preview.setText(R.string.photoselect_preview);
            preview.setEnabled(false);
            finish.setText(R.string.photoselect_done);
            finish.setEnabled(false);
        } else {
            preview.setText(String.format(getString(R.string.photoselect_unit_preview), size));
            preview.setEnabled(true);
            finish.setText(String.format(getString(R.string.photoselect_unit_done), size, maxSize));
            finish.setEnabled(true);
        }
    }

    /**
     * 显示目录列表
     */
    private void showFolderListDialog() {
        // 1.没有目录数据就不展示了
        // 2.只有拍照
        if (folders == null || folders.size() == 0 || (isShowCamera && folders.size() == 1)) {
            return;
        }
        if (folderDialog == null) {
            folderDialog = new AutoBottomMenuDialog(this);
            ListView listview = new ListView(this);
            folderDialog.addCustomView(listview);
            listview.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, getResources().getDisplayMetrics().heightPixels / 5 * 3));
            folderAdapter = new ChoosePhotoFolderAdapter();
            listview.setAdapter(folderAdapter);
            listview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                @Override
                public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                    chooseFolderItem(position);
                    folderDialog.dismiss();
                }
            });
            folderAdapter.clear();
            folderAdapter.addAll(folders);
            folderAdapter.showPosition(currentFolderPosition);
            folderAdapter.notifyDataSetChanged();
            // 方法1
            WindowManager.LayoutParams params = folderDialog.getWindow().getAttributes();
            params.y = footer.getMeasuredHeight();
            // 方法2
//			View view = new View(this);
//			view.setBackgroundColor(Color.TRANSPARENT);
//			view.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, footer.getMeasuredHeight()));
//			folderDialog.addCustomView(view);
//			view.setOnClickListener(new View.OnClickListener() {
//				@Override
//				public void onClick(View view) {
//					folderDialog.dismiss();
//				}
//			});
        }

        folderDialog.show();
    }

    /**
     * 选择目录
     *
     * @param position
     */
    private void chooseFolderItem(int position) {
        if (folders == null && folders.size() == 0) {
            return;
        }
        if (position >= folders.size() || position < 0) {
            position = 0;
        }
        currentFolderPosition = position;
        category_btn.setText(folders.get(position).getTitle());
        imageAdapter.clear();
        imageAdapter.addAll(folders.get(position).getImages());
        imageAdapter.notifyDataSetChanged();
        if (folderAdapter != null) {
            folderAdapter.showPosition(position);
            folderAdapter.notifyDataSetInvalidated();
        }
    }

    @Override
    public void onClick(View v) {
        int i = v.getId();
        if (i == R.id.category_btn) {// 目录按钮
            showFolderListDialog();
        } else if (i == R.id.preview) {// 预览
            showPreview();
        } else if (i == R.id.finish) {// 完成
            finishSuccess();
        } else if (i == R.id.back) {// 返回
            finish();
        }
    }

    private void finishSuccess() {
        ArrayList<String> images = new ArrayList<>();
        ArrayList<String> videos = new ArrayList<>();
        for (MediaInfo ii : imageAdapter.getChecked()) {
            if (ii.getType() == MediaInfo.TYPE_VIDEO) {
                videos.add(ii.getPath());
            } else {
                images.add(ii.getPath());
            }
        }
        Intent result = new Intent();
        result.putStringArrayListExtra(EXTRA_OUT_IMAGES, images);
        result.putStringArrayListExtra(EXTRA_OUT_VIdEOS, videos);
        setResult(Activity.RESULT_OK, result);
        super.finish();
    }

    private void finishOne(String picPath) {
        ArrayList<String> images = new ArrayList<>();
        images.add(picPath);
        Intent result = new Intent();
        result.putStringArrayListExtra(EXTRA_OUT_IMAGES, images);
        setResult(Activity.RESULT_OK, result);
        super.finish();
    }

    private void finishIncrement(String picPath) {
        ArrayList<String> images = new ArrayList<>();
        ArrayList<String> videos = new ArrayList<>();
        for (MediaInfo ii : imageAdapter.getChecked()) {
            if (ii.getType() == MediaInfo.TYPE_VIDEO) {
                videos.add(ii.getPath());
            } else {
                images.add(ii.getPath());
            }
        }
        if (images.size() == maxImageSize) {
            images.remove(0);
            images.add(picPath);
        } else {
            images.add(picPath);
        }
        Intent result = new Intent();
        result.putStringArrayListExtra(EXTRA_OUT_IMAGES, images);
        result.putStringArrayListExtra(EXTRA_OUT_VIdEOS, videos);
        setResult(Activity.RESULT_OK, result);
        super.finish();
    }


    public void finishResult(String picpath) {
        if (choosePhotoCallBackInterface.isIncrementFinish()) {
            if (TextUtils.isEmpty(picpath)) {
                finishSuccess();
            } else {
                finishIncrement(picpath);
            }
        } else {
            if (TextUtils.isEmpty(picpath)) {
                finish();
            } else {
                finishOne(picpath);
            }
        }
    }

    private void showPreview() {
        ArrayList<String> images = new ArrayList<>();
        ArrayList<Integer> index = new ArrayList<>();
        ArrayList<String> videos = new ArrayList<>();
        for (MediaInfo ii : imageAdapter.getChecked()) {
            if (ii.getType() == MediaInfo.TYPE_VIDEO) {
                videos.add(ii.getPath());
            } else {
                images.add(ii.getPath());
                index.add(1);
            }
        }
        new PreviewPhotoIntent(this, PreviewPhotoPreviewActivity.EXTRA_TYPE_CHECK)
                .setPhotoDisplayInterface(photoDisplayInterface.getClass())
                .setImages(images)
                .setChecked(index)
                .setPosition(0)
                .startActivity(this, REQUESTCODE_PREVIEW);
    }

    private List<MediaInfo> getCheckedImages() {
        ArrayList<MediaInfo> images = new ArrayList<>();
        for (MediaInfo ii : imageAdapter.getChecked()) {
            if (ii.getType() == MediaInfo.TYPE_VIDEO) {
            } else {
                images.add(ii);
            }
        }
        return images;
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode != Activity.RESULT_OK) {
            return;
        }
        if (requestCode == REQUESTCODE_PREVIEW) {
            ArrayList<Integer> list = data.getExtras().getIntegerArrayList(PreviewPhotoBaseActivity.EXTRA_OUT_CHECK);
            for (int i = 0, count = list.size(); i < count; i++) {
                if (list.get(i) == 0) {
                    imageAdapter.getChecked().remove(i);
                }
            }
            imageAdapter.notifyDataSetInvalidated();
            int size = imageAdapter.getChecked().size();
            updateSelectedUI(size);
        } else {
            if (choosePhotoCallBackInterface != null) {
                String picpath = choosePhotoCallBackInterface.onResultActivityByCamera(handler, requestCode, resultCode, data);
                if (choosePhotoCallBackInterface.isDirectFinish()) {
                    finishResult(picpath);
                }
            }
        }
    }

    public static Message getFinishMessage(String picpath) {
        Message message = new Message();
        message.what = 2;
        message.obj = picpath;
        return message;
    }

    private static class ChoosePhotoHandler extends Handler {
        private final WeakReference<ChoosePhotoActivity> mActivity;

        public ChoosePhotoHandler(ChoosePhotoActivity activity) {
            this.mActivity = new WeakReference<ChoosePhotoActivity>(activity);
        }

        @Override
        public void handleMessage(Message msg) {
            if (mActivity != null && mActivity.get() != null) {
                if (msg.what == 1) {
                    if (msg.obj != null) {
                        List<MediaFolder> folders = ((List<MediaFolder>) msg.obj);
                        if (msg.obj != null) {
                            mActivity.get().folders = folders;
                            mActivity.get().chooseFolderItem(0);
                        }
                    }
                } else if (msg.what == 2) {
                    if (msg.obj == null || msg.obj instanceof String) {
                        mActivity.get().finishResult((String) msg.obj);
                    }
                }
            }
        }
    }

    private final int REQUEST_PERMISSION = 101;

    public boolean requestPermission(String[] permissions) {
        if (checkPermissions(permissions)) {
            return true;
        } else {
            List<String> needPermissions = getDeniedPermissions(permissions);
            ActivityCompat.requestPermissions(this, needPermissions.toArray(new String[needPermissions.size()]), REQUEST_PERMISSION);
            return false;
        }
    }

    private List<String> getDeniedPermissions(String[] permissions) {
        List<String> needRequestPermissionList = new ArrayList<>();
        for (String permission : permissions) {
            if (ContextCompat.checkSelfPermission(this, permission) !=
                    PackageManager.PERMISSION_GRANTED ||
                    ActivityCompat.shouldShowRequestPermissionRationale(this, permission)) {
                needRequestPermissionList.add(permission);
            }
        }
        return needRequestPermissionList;
    }

    private boolean checkPermissions(String[] permissions) {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
            return true;
        }

        for (String permission : permissions) {
            if (ContextCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED) {
                return false;
            }
        }
        return true;
    }

    private boolean verifyPermissions(int[] grantResults) {
        for (int grantResult : grantResults) {
            if (grantResult != PackageManager.PERMISSION_GRANTED) {
                return false;
            }
        }
        return true;
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == REQUEST_PERMISSION) {
            if (verifyPermissions(grantResults)) {
                handleData();
            } else {
                Toast.makeText(this, "lack some permissions", Toast.LENGTH_SHORT).show();
                finish();
            }
        }
    }

    @Override
    protected void onDestroy() {
        photoDisplayInterface.clearMemoryCache();
        super.onDestroy();
    }
}
